import { Request, Response } from "express";
import { uploadAvatarImg } from "../../multer/upload";
import { uploadExcel } from "../../multer/uploadExcel";
import collegeService from "../../service/collegeService";
import teacherService from '../../service/teacherService'
import { encryption, decrypt, createToken, processData } from '../../utils/index'
import { validateRegisterForm, validateLoginForm, validateUpdateInfoForm, validatePhoneAndEmail,validateExcelForm } from './validate'

class TeacherController {

  // 登录
  async login(req: Request, res: Response) {
    // 验证表单参数
    let validateRes = validateLoginForm(req.body)
    if (validateRes) return res.gem(validateRes)
    // 查找账号
    const { account, password } = req.body
    const userInfo = await teacherService.findOneByAccount(account)
    if (!userInfo) return res.gem('账号不存在！')
    // 密码解密进行对比
    const isRight = decrypt(password, String(userInfo.password)) // 密码比较 
    if (!isRight) return res.gem('密码错误！')
    // 用户状态
    if (!userInfo.state) return res.gem('账号已被禁用！')
    // 生成 token
    const token = createToken(Number(userInfo.id))
    delete userInfo.password
    res.gsmdt(userInfo, token)
  }

  // 创建
  async register(req: Request, res: Response) {
    const form = req.body
    // 验证表单参数
    const validateRes = validateRegisterForm(form)
    if (validateRes) return res.gem(validateRes)
    // 先查询账号是否存在
    form.identify = form.account  // 编号默认为账号（@前号码）
    form.account = `${form.account}@gk.com`
    const admin = await teacherService.findOneByAccount(form.account)
    if (admin) return res.gem('账号已存在！')
    // 密码默认为123456
    form.password = '123456'
    // 如果没有传递状态，则默认为 true
    form.state = form.state ? Boolean(form.state) : true
    // 默认角色就为 0（管理员）
    form.role = 1
    // 密码加密
    form.password = encryption(form.password)
    // 保存数据倒数库
    const saveResult = await teacherService.save(form)
    if (saveResult) res.gsm('创建成功！')
    else res.gem('创建失败！')
  }

  // 分页查询所有admin用户， 如果不传参数，默认查询全部
  async findAll(req: Request, res: Response) {
    // const total = await teacherService.teacherCount()
    // let page_num = parseInt(req.query.page_num) || 1 // 如果page_num为0就默认为1
    // let page_size = parseInt(req.query.page_size) || 10

    // // 计算skip
    // let skip = (page_num - 1) * page_size
    // const result = await teacherService.find(skip, page_size)
    // result.forEach(item => delete item.password) // 不返回密码
    // res.gsmdl(total, result)
    const datas = await teacherService.findAll()
    res.gsmd(datas)
  }

  // 根据id查找 teacher 用户
  async findByIdCon(req: Request, res: Response) {
    const { id } = req.params
    const result = await teacherService.findById(id)
    delete result.password
    res.gsmd(result)
  }

  // 更新头像
  async updateAvatar(req: Request, res: Response) {
    const { id, base64 } = req.body
    const updateRes = await teacherService.updateAvatar(id, base64)
    if (updateRes.affected < 1) return res.gem('更新头像失败！')
    res.gsm('更新头像成功！')
  }

  // 根据编号查询
  async findByIdentify(req: Request, res: Response) {
    const { identify } = req.params
    const result = await teacherService.findByIdentify(identify.toLocaleLowerCase())
    if (!result) return res.gem('查无此教师，请检查编号是否正确！')
    delete result.password
    res.gsmd(result)
  }

  // 根据编号查询
  async findByPhone(req: Request, res: Response) {
    const { phone } = req.params
    const result = await teacherService.findByPhone(phone)
    if (!result) return res.gem('查无此教师，请检查手机号码是否正确！')
    delete result.password
    res.gsmd(result)
  }

  // 修改密码
  async updatePassword(req: Request, res: Response) {
    const form = req.body
    if (form.newPass.length < 6 || form.newPass.length > 10) return res.gem('密码长度必须是6-10之间！')
    if (form.newPass !== form.checkPass) return res.gem('两次输入的密码不一致！')
    const user = await teacherService.findById(form.id)
    // 校验密码
    const isRight = decrypt(form.oldPass, user.password)
    if (!isRight) return res.gem('旧密码错误！')

    // 密码加密存储
    form.checkPass = encryption(form.checkPass)
    const result = await teacherService.updatePassWord(form.id, form.checkPass)
    if (result.affected < 1) return res.gem('修改密码失败！')
    res.gsm('修改密码成功！')
  }

  // 修改个人信息
  async updateInfo(req: Request, res: Response) {
    const form = req.body
    // 表单验证
    const errorMsg = validateUpdateInfoForm(form)
    if (errorMsg) return res.gem(errorMsg)
    // 如果修改了账号，则编号也得修改
    if (form.account) {
      form.identify = form.account.split('@')[0]
    }
    // 修改信息
    // 先取出id，然后删除form中的id（数据库中为_id，这里为id，不一样会导致修改时添加id字段）
    const userId = form.id
    delete form.id
    // 修改信息
    const result = await teacherService.updateInfo(userId, form)
    if (result.affected < 0) return res.gem('修改信息失败！')
    const user = await teacherService.findById(userId)
    res.gsmd(user, '信息修改成功！')
  }

  // 上传头像
  async uploadAva(req: Request, res: Response) {
    try {
      let uploadData: any = await uploadAvatarImg(req, res)
      // console.log('uploadRes: ',uploadData);
      const uploadRes = await teacherService.updateAvatar(uploadData.id, uploadData.img_src)
      if (uploadRes.affected >= 1) {
        res.gsm('上传头像成功！')
      }
    } catch (err) {
      if (err.error) {
        res.gem(err.error)
      } else {
        res.gem('上传失败，图片大小限制为2mb！')
      }
    }
  }

  // 根据姓名关键词模糊查询
  async findByNameKey(req: Request, res: Response) {
    const { name } = req.body
    const page_num = parseInt(req.body.page_num) || 1
    const page_size = parseInt(req.body.page_size) || 10

    const skip = (page_num - 1) * page_size

    const count = await teacherService.findByNameKeyCount(name)
    const users = await teacherService.findByNameKey(name, skip, page_size)

    if (!users) res.gem('查无数据！')
    res.gsmdl(count, users)
  }

  // 根据 id 进行删除
  async deleteById(req: Request, res: Response) {
    const { id } = req.params
    const user = await teacherService.findById(id)
    if (!user) return res.gem('该用户不存在！')
    const result = await teacherService.deleteById(id)
    if (result.affected >= 1) {
      return res.gsm('删除用户成功！')
    } else {
      return res.gem('删除用户失败！')
    }
  }

  // 修改用户状态
  async updateState(req: Request, res: Response) {
    const id = req.params.id
    const user = await teacherService.findById(id)
    if (!user) return res.gem('该用户不存在')
    const result = await teacherService.updateState(id, !user.state)
    if (result.affected < 1) return res.gem('用户状态修改失败！')
    res.gsm('用户状态修改成功！')
  }

  // 上传excel文件，批量创建用户
  async createManyUser(req: Request, res: Response) {
    try {
      const excelData: any = await uploadExcel(req)
      const cnNameToEnName = {
        姓名: 'name',
        账号: 'account',
        性别: 'gender',
        手机号码: 'phone',
        邮箱: 'email',
        所属院系: 'college'
      }
      let isOk = true
      // 校验是否有需要的表头，只需要判断第一个对象即可
      Object.keys(cnNameToEnName).forEach((k: any) => {
        if (!excelData[0].hasOwnProperty(k)) {
          isOk = false
          return res.gem(`该文件表头缺失【${k}】字段，请重新上传！`)
        }
      })
      // 处理表头格式
      const newExcelData = processData(cnNameToEnName, excelData)
      let user: any = {}

      // 获取全部学院，后续校验所属学院是否存在
      const colleges = await collegeService.findAll()
      const college_names = colleges.map(item => item.college_name)

      newExcelData.forEach(async (item: any) => {
        // 校验必填项是否为空
        const msg = validateExcelForm(item)
        if (isOk && msg) {
          isOk = false
          return res.gem(msg)
        }
        // 校验账号格式（必须以 @admin.com 结尾）
        if (isOk && !item.account.endsWith('@gk.com')) {
          isOk = false
          return res.gem(`文件中有不符合规则的账号 ——【${item.account}】，请重新上传！`)
        }
        // 校验手机号码和邮箱（可以没有，但有则必须正确）
        const validateRes = validatePhoneAndEmail(item)
        if (isOk && validateRes?.msg) {
          isOk = false
          return res.gem(`文件中有不符合规则的${validateRes.msg} ——【${validateRes.value}】，请重新上传！`)
        }
        // 校验性别是否正确
        const isGenderOk = item.gender === '男' || item.gender === '女'
        if (isOk && !isGenderOk) {
          isOk = false
          return res.gem(`文件中有填写错误的性别 ——【${item.gender}】，请重新上传！`)
        }

        // 校验所属学院是否存在
        const isCollege = college_names.find(c => c === item.college)
        if (isOk && !isCollege) {
          isOk = false
          return res.gem(`文件中某所属学院【${item.college}】填写有误，请重新上传！`)
        }

        if (isOk) {
          const findRes = await teacherService.findOneByAccount(item.account)
          if (isOk && findRes) {
            isOk = false
            user = findRes
            return
          }
        }
        // 校验账号是否已存在

      })
      if (isOk) {
        setTimeout(async () => {
          if (Object.keys(user).length !== 0) {
            return res.gem(`文件中的账号【${user.account}】已存在，请重新上传！`)
          } else {
            newExcelData.forEach((item: any) => {
              // 处理数据
              item.phone = String(item.phone)
              item.identify = item.account.split('@')[0]
              item.password = encryption('123456')
              item.state = true
              item.role = 1
            })
            const saveRes = await teacherService.saveMany(newExcelData)
            if (saveRes.length !== 0) {
              res.gsm('批量创建用户成功！')
            } else {
              res.gem('批量创建用户失败！')
            }
          }
        }, 10)
      }
    } catch (error) {
      if (error.msg) {
        res.gem(error.msg)
      }
    }
  }
}

export default new TeacherController()